#include <bits/stdc++.h>
#define ps putchar(' ')
#define pe putchar('\n')
#define int long long
#define ls p << 1
#define rs p << 1 | 1
#define mid ((l + r) >> 1)
using namespace std;
inline int read()
{
    int ans = 0, f = 0;
    char c = getchar();
    while (!isdigit(c))
        f |= c == '-', c = getchar();
    while (isdigit(c))
        ans = (ans << 3) + (ans << 1) + c - 48, c = getchar();
    return f ? -ans : ans;
}
void write(int x)
{
    if (x < 0)
        putchar('-'), x = -x;
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + 48);
}
const int N = 1e6 + 5, mod = 998244353;
int n, m, ans, a[N];
namespace sub
{
    const int N = 1e3 + 5;
    int f[N][20];
    struct Path
    {
        vector<int> g[N];
        int cnt, rt, dfn[N], top[N], d[N], fa[N], si[N], son[N];
        inline void add_edge(int u, int v) { g[u].push_back(v), g[v].push_back(u); }
        void dfs(int u, int fat)
        {
            d[u] = d[fa[u] = fat] + 1, si[u] = 1;
            for (int v : g[u])
                if (v != fat)
                {
                    dfs(v, u), si[u] += si[v];
                    if (si[son[u]] < si[v])
                        son[u] = v;
                }
        }
        void dfs2(int u, int Top)
        {
            dfn[u] = ++cnt, top[u] = Top;
            if (!son[u])
                return;
            dfs2(son[u], Top);
            for (int v : g[u])
                if (v != fa[u] && v != son[u])
                    dfs2(v, v);
        }
        inline void init(int root) { dfs(rt = root, 0), dfs2(rt, rt); }
        inline int LCA(int u, int v)
        {
            while (top[u] != top[v])
            {
                if (d[top[u]] < d[top[v]])
                    swap(u, v);
                u = fa[top[u]];
            }
            return d[u] < d[v] ? u : v;
        }
    } t1, t2;
    inline void solve(int u, int v)
    {
        int lca = t1.LCA(u, v), val = t2.d[t2.LCA(a[u], a[v])];
        if (t1.dfn[u] > t1.dfn[v])
            swap(u, v);
        if (u == lca)
        {
            int s = v;
            for (int i = 19; i >= 0; --i)
                if (t1.d[f[s][i]] > t1.d[u])
                    s = f[s][i];
            ans = (ans + (n - t1.si[s]) * t1.si[v] % mod * val % mod) % mod;
        }
        else
            ans = (ans + t1.si[u] * t1.si[v] % mod) % mod;
    }
    inline void main()
    {
        int root = 0;
        for (int i = 1; i <= n; ++i)
        {
            int fa = read();
            fa ? t1.add_edge(i, f[i][0] = fa) : (void)(root = i);
        }
        t1.init(root), root = 0;
        for (int i = 1; i <= m; ++i)
        {
            int fa = read();
            fa ? t2.add_edge(i, fa) : (void)(root = i);
        }
        t2.init(root);
        for (int i = 1; i <= n; ++i)
            a[i] = read();
        for (int j = 1; j <= 19; ++j)
            for (int i = 1; i <= n; ++i)
                f[i][j] = f[f[i][j - 1]][j - 1];
        for (int i = 1; i <= n; ++i)
            for (int j = i + 1; j <= n; ++j)
                solve(i, j);
        write(ans);
    }
}
signed main()
{
    freopen("tree.in", "r", stdin);
    freopen("tree.out", "w", stdout);
    n = read(), m = read();
    if (n <= 1e3 && m <= 1e3)
    {
        sub::main();
        return 0;
    }
    return 0;
}